KAFKA-16154: Broker returns offset for LATEST_TIERED_TIMESTAMP#16783
Conversation
showuon
left a comment
There was a problem hiding this comment.
Thanks for the PR. Left some comments.
| * Used to retrieve the offset with the local log start offset, | ||
| * log start offset is the offset of a log above which reads are guaranteed to be served | ||
| * from the disk of the leader broker, when Tiered Storage is not enabled, it behaves the same | ||
| * as the earliest timestamp |
There was a problem hiding this comment.
nit: Used to retrieve the offset with the local log start offset[.]
[Local] log start offset is the offset of a log above which reads are guaranteed to be served from the disk of the leader broker.
Note: When tiered storage is not enabled, it behaves the same as retrieving the earliest timestamp offset.
| * Used to retrieve the offset with the highest offset of data stored in remote storage, | ||
| * and when Tiered Storage is not enabled, we won't return any offset (i.e. Unknown offset) |
There was a problem hiding this comment.
nit:
Used to retrieve the offset with the highest offset of data stored in remote storage[.]
Note: When tiered storage is not enabled, we won't return any offset (i.e. [will return] unknown offset.
There was a problem hiding this comment.
Thanks for the comments, already fixed them in the latest commit.
There was a problem hiding this comment.
Overall LGTM! We need integration tests for it. We should add some test like DeleteTopicTest using ExpectListOffsetsAction. I expected it should work like this (I didn't try):
// send records to partition 0
.expectSegmentToBeOffloaded(broker0, topicA, p0, 0, new KeyValueSpec("k0", "v0"))
.expectSegmentToBeOffloaded(broker0, topicA, p0, 1, new KeyValueSpec("k1", "v1"))
.expectEarliestLocalOffsetInLogDirectory(topicA, p0, 2L)
.produce(topicA, p0, new KeyValueSpec("k0", "v0"), new KeyValueSpec("k1", "v1"),
new KeyValueSpec("k2", "v2"))
// new verification:
.expectListOffsets(topicA, 0, LatestTierSpec, 0(?)) <-- should create an expected `EpochEntry` instance
Let me know if you have any problem.
|
I mean, we can create a test called |
Thanks @showuon , I enabled remote storage in GetOffsetShellTest, do we still need the test you mentioned above ? |
|
|
||
| private static List<ClusterConfig> withRemoteStorage() { | ||
| Map<String, String> serverProperties = new HashMap<>(); | ||
| serverProperties.put(RemoteLogManagerConfig.DEFAULT_REMOTE_LOG_METADATA_MANAGER_CONFIG_PREFIX + TopicBasedRemoteLogMetadataManagerConfig.REMOTE_LOG_METADATA_TOPIC_REPLICATION_FACTOR_PROP, "1"); |
There was a problem hiding this comment.
Could we set remote.log.metadata.topic.num.partitions to 1 (default is 50) to speed up the test?
showuon
left a comment
There was a problem hiding this comment.
Overall LGTM! Left some comments. Thanks.
| Map<String, String> zkProperties = new HashMap<>(serverProperties); | ||
| zkProperties.put(RemoteLogManagerConfig.REMOTE_LOG_METADATA_MANAGER_LISTENER_NAME_PROP, "PLAINTEXT"); | ||
|
|
||
| Map<String, String> raftProperties = new HashMap<>(serverProperties); | ||
| raftProperties.put(RemoteLogManagerConfig.REMOTE_LOG_METADATA_MANAGER_LISTENER_NAME_PROP, "EXTERNAL"); |
There was a problem hiding this comment.
Could we add a comment here to explain why we need 2 different settings?
There was a problem hiding this comment.
Correct me if I'm wrong, after spending some time digging through the code I found out that in Type.ZK the default listener name is PLAINTEXT and is set via
kafka/core/src/test/java/kafka/test/junit/ZkClusterInvocationContext.java
Lines 312 to 316 in 96989e4
while in Type.KRAFT/Type.CO_KRAFT, it is
EXTERNAL, see kafka/core/src/test/java/kafka/testkit/KafkaClusterTestKit.java
Lines 324 to 332 in 1084d3b
Another thing is that ClusterConfig#setListenerName only works under ZK mode, in KRAFT it is useless. Perhaps we should make it work under Raft mode too. gentle ping @chia7712, any thoughts ?
There was a problem hiding this comment.
@brandboat you are right. Could you please open a jira for that? KRAFT should honor the listener name and security protocol from ClusterConfig.
There was a problem hiding this comment.
thanks for double checking, filed https://issues.apache.org/jira/browse/KAFKA-17256
| sendProducerRecords(this::getTopicName); | ||
| } | ||
|
|
||
| private void setUpRemoteLogTopics() { |
There was a problem hiding this comment.
I'll add some comment for this method. Ex:
In this method, we'll create 4 topics and produce records to the log like this:
topicRLS1 -> 1 segment
topicRLS2 -> 2 segments (1 local log segment + 1 segment in the remote storage)
topicRLS3 -> 3 segments (1 local log segment + 2 segments in the remote storage)
topicRLS4 -> 4 segments (1 local log segment + 3 segments in the remote storage)
There was a problem hiding this comment.
Thank you for the detailed comment, this will certainly help others grasp the details of the test 😃
| // test topics enable remote log storage | ||
| TestUtils.waitForCondition(() -> | ||
| Arrays.asList( | ||
| new Row("topicRLS2", 0, 0L), | ||
| new Row("topicRLS3", 0, 1L), | ||
| new Row("topicRLS4", 0, 2L)) |
There was a problem hiding this comment.
I'll add 1 more line for the comment to explain why topicRLS1 has no result:
topicRLS1 has no result because there's no log segments being uploaded to the remote storage
There was a problem hiding this comment.
Everything has been addressed in the latest commit, thank you
chia7712
left a comment
There was a problem hiding this comment.
@brandboat thanks for this nice patch. I leave some comments for this PR. The naming is part of public APIs, so we must have "accurate" naming before release.
| serverProperties.put(ServerLogConfigs.LOG_INITIAL_TASK_DELAY_MS_CONFIG, "100"); | ||
| serverProperties.put(RemoteLogManagerConfig.REMOTE_LOG_METADATA_MANAGER_LISTENER_NAME_PROP, "EXTERNAL"); | ||
|
|
||
| return Arrays.asList( |
There was a problem hiding this comment.
We can set listener name for all types even though setListenerName is no-op for kraft/co-kraft mode. That can simplify the code and it is still valid.
return Collections.singletonList(
ClusterConfig.defaultBuilder()
.setTypes(new HashSet<>(Arrays.asList(ZK, KRAFT, CO_KRAFT)))
.setServerProperties(serverProperties)
.setListenerName("EXTERNAL")
.build());| return OffsetSpec.latest(); | ||
| case "max-timestamp": | ||
| return OffsetSpec.maxTimestamp(); | ||
| case "earliest-local": |
There was a problem hiding this comment.
Could you please update docs?
| * and when Tiered Storage is not enabled, we won't return any offset (i.e. Unknown offset) | ||
| * Used to retrieve the highest offset of data stored in remote storage. | ||
| * <br/> | ||
| * Note: When tiered storage is not enabled, we will return unknown offset. |
There was a problem hiding this comment.
Could you please add test for this scenario?
There was a problem hiding this comment.
| * Local log start offset is the offset of a log above which reads | ||
| * are guaranteed to be served from the disk of the leader broker. | ||
| * <br/> | ||
| * Note: When tiered Storage is not enabled, it behaves the same as retrieving the earliest timestamp offset. |
There was a problem hiding this comment.
Could you please add test for it?
| * <br/> | ||
| * Note: When tiered Storage is not enabled, it behaves the same as retrieving the earliest timestamp offset. | ||
| */ | ||
| public static OffsetSpec earliestLocalSpec() { |
There was a problem hiding this comment.
This is unrelated to this PR. The other specs don't use Spec as postfix. Maybe we should align the naming before release?
There was a problem hiding this comment.
OK, I'll remove the postfix
| * Note: When tiered storage is not enabled, we will return unknown offset. | ||
| */ | ||
| public static OffsetSpec latestTierSpec() { | ||
| return new LatestTierSpec(); |
There was a problem hiding this comment.
This is not related to this PR, but KIP-1005 (https://cwiki.apache.org/confluence/display/KAFKA/KIP-1005%3A+Expose+EarliestLocalOffset+and+TieredOffset) calls it LatestTieredSpec rather than LatestTierSpec
ping @FrankYang0529 as you are the author of #16781
There was a problem hiding this comment.
Thanks for finding this. Yes, we should follow the KIP. @brandboat, could you fix it in this PR? I'm afraid if I create another PR may block your progress.
There was a problem hiding this comment.
Everything has been addressed, thanks everyone.
|
@brandboat, I think we also need to update L296-297 in GetOffsetShell |
FrankYang0529
left a comment
There was a problem hiding this comment.
LGTM. Thanks for the patch.
| serverProperties.put(RemoteLogManagerConfig.REMOTE_LOG_STORAGE_SYSTEM_ENABLE_PROP, "true"); | ||
| serverProperties.put(RemoteLogManagerConfig.REMOTE_STORAGE_MANAGER_CLASS_NAME_PROP, LocalTieredStorage.class.getName()); | ||
| serverProperties.put(RemoteLogManagerConfig.REMOTE_LOG_MANAGER_TASK_INTERVAL_MS_PROP, "1000"); | ||
| serverProperties.put(TopicBasedRemoteLogMetadataManagerConfig.REMOTE_LOG_METADATA_TOPIC_PARTITIONS_PROP, "1"); |
There was a problem hiding this comment.
I think we should add RemoteLogManagerConfig.DEFAULT_REMOTE_LOG_METADATA_MANAGER_CONFIG_PREFIX to set REMOTE_LOG_METADATA_TOPIC_PARTITIONS_PROP, but I might be wrong. Could you confirm the current change takes effect in the remote log topics?
There was a problem hiding this comment.
yeah... I missed that. Thank you
|
failed test passed in my local env: ./gradlew cleanTest \
core:test --tests kafka.zk.ZkMigrationFailoverTest.testDriverSkipsEventsFromOlderEpoch \
tool:test --tests org.apache.kafka.tools.LeaderElectionCommandTest.testPreferredReplicaElection \
clients:test --tests org.apache.kafka.common.record.MemoryRecordsBuilderTest.testBuffersDereferencedOnClose |
This pr support EarliestLocalSpec LatestTierSpec in GetOffsetShell, and add integration tests. Reviewers: Luke Chen <showuon@gmail.com>, Chia-Ping Tsai <chia7712@gmail.com>, PoAn Yang <payang@apache.org>
This pr support EarliestLocalSpec LatestTierSpec in GetOffsetShell, and add integration tests.
Committer Checklist (excluded from commit message)